package cn.leedsoft.and.crimeintent.manager.run_tracker;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.location.Location;
import cn.leedsoft.and.crimeintent.model.run_tracker.Run;
import com.google.common.collect.Lists;

import java.util.Date;
import java.util.List;

/**
 * Created by leeds on 2016/9/6 10:53.
 */
public class RunDatabaseHelper extends SQLiteOpenHelper {
    private static final int VERSION = 1;
    private static final String DB_NAME = "run.sqlite";
    private static final String TABLE_RUN = "run";
    private static final String TABLE_LOCATION = "location";
    private static final String COLUMN_RUN__START_DATE = "start_date";
    private static final String COLUMN_RUN__ID = "_id";
    private static final String COLUMN_LOCATION__TIMESTAMP = "timestamp";
    private static final String COLUMN_LOCATION__LATITUDE = "latitude";
    private static final String COLUMN_LOCATION__LONGITUDE = "longitude";
    private static final String COLUMN_LOCATION__ALTITUDE = "altitude";
    private static final String COLUMN_LOCATION__PROVIDER = "provider";
    private static final String COLUMN_LOCATION__RUN_ID = "run_id";

    public RunDatabaseHelper(Context context) {
        super(context, DB_NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {//on db create callback
        //create table run
        db.execSQL("create table run (" +
                "_id integer primary key autoincrement, start_date integer)");
        //create table location
        db.execSQL("create table location (" +
                "timestamp integer, latitude real, longitude real, altitude real, provider varchar(100)," +
                "run_id integer references run(_id))");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    /**
     * @param run
     * @return the row ID of the newly inserted row, or -1 if an error occurred
     */
    public long insertRun(Run run) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_RUN__START_DATE, run.getStartDate().getTime());
        return getWritableDatabase().insert(TABLE_RUN, null, cv);
    }

    public long insertLocation(long runId, Location location) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_LOCATION__TIMESTAMP, location.getTime());
        cv.put(COLUMN_LOCATION__LATITUDE, location.getLatitude());
        cv.put(COLUMN_LOCATION__LONGITUDE, location.getLongitude());
        cv.put(COLUMN_LOCATION__ALTITUDE, location.getAltitude());
        cv.put(COLUMN_LOCATION__PROVIDER, location.getProvider());
        cv.put(COLUMN_LOCATION__RUN_ID, runId);
        return getWritableDatabase().insert(TABLE_LOCATION, null, cv);
    }

    public List<Run> queryRuns() {
        List<Run> res = Lists.newArrayList();//返回list size=0 比返回null 更安全。避免null检查。

        RunCursor cursor = queryRunCursor();
        while (cursor.moveToNext()) {
            res.add(cursor.getRun());
        }
        cursor.close();
        return res;
    }

    public RunCursor queryRunCursor() {
        //        Cursor cursor = getReadableDatabase().query(TABLE_RUN, null, null, null, null, null, COLUMN_RUN__START_DATE + " asc");
        Cursor cursor = getReadableDatabase().rawQuery("select * from run order by start_date desc", null);
        return new RunCursor(cursor);
    }

    public Run queryRun(long runId) {
        Cursor cursor = getReadableDatabase().rawQuery("select * from run where _id=? order by start_date desc", new String[]{String.valueOf(runId)});
        if(cursor.getCount() == 0) return null;
        RunCursor runCursor = new RunCursor(cursor);
        runCursor.moveToFirst();
        Run run = runCursor.getRun();
        runCursor.close();
        return run;
    }

    public Location queryLastLocation(long runId) {
        Cursor cursor = getReadableDatabase().rawQuery("select * from location where run_id=? order by timestamp desc limit 1", new String[]{String.valueOf(runId)});
        if (cursor.getCount() == 0) return null;
        cursor.moveToFirst();
        Location location = new LocationCursor(cursor).getLocation();
        cursor.close();
        return location;
    }

    public static class RunCursor extends CursorWrapper {//将查询的原始数据封装----wrapper---->model 模型对象
        //RunCursor主要负责将run表中的各个记录转化为Run实例
        /**
         * Creates a cursor wrapper.
         *
         * @param cursor The underlying cursor to wrap.
         */
        public RunCursor(Cursor cursor) {
            super(cursor);
        }

        public Run getRun() {
            if(isBeforeFirst() || isAfterLast()) {
                return null;
            }
            Run run = new Run();
            run.setId(getLong(getColumnIndex(COLUMN_RUN__ID)));
            run.setStartDate(new Date(getLong(getColumnIndex(COLUMN_RUN__START_DATE))));
            return run;
        }
    }

    public static class LocationCursor extends CursorWrapper {

        /**
         * Creates a cursor wrapper.
         *
         * @param cursor The underlying cursor to wrap.
         */
        public LocationCursor(Cursor cursor) {
            super(cursor);
        }

        public Location getLocation() {
            if(isBeforeFirst() || isAfterLast()) {
                return null;
            }
            Location location = new Location(getString(getColumnIndex(COLUMN_LOCATION__PROVIDER)));
            location.setLatitude(getDouble(getColumnIndex(COLUMN_LOCATION__LATITUDE)));
            location.setLongitude(getDouble(getColumnIndex(COLUMN_LOCATION__LONGITUDE)));
            location.setAltitude(getDouble(getColumnIndex(COLUMN_LOCATION__ALTITUDE)));
            location.setTime(getLong(getColumnIndex(COLUMN_LOCATION__TIMESTAMP)));
            return location;
        }
    }

}
